﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using HengTong.Model;
using HengTong.Model.Db;
using HengTong.Model.Db.Hr;
using HengTong.Model.Db.Hr.Bill;
using HengTong.Model.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TiaoTaoHelper.Models;
using TiaoTaoHelper.Wtm.Models;
using UUIDNext;

namespace HengTong.ViewModel.Hr.SysHrStaffPoolVms
{
    public partial class SysHrStaffPoolBatchVm
    {
        /// <summary>
        /// 批量生成招聘发布申请
        /// 将选中的用人需求池记录生成对应的招聘发布申请单
        /// </summary>
        /// <returns>生成招聘发布申请主表id</returns>
        public async Task<Result<Guid>> GenerateRecruitPublishRequestAsync()
        {
            var logger = Wtm.ServiceProvider.GetRequiredService<ILogger<SysHrStaffPoolBatchVm>>();

            if (Ids == null || !Ids.Any())
            {
                return new Result<Guid>("请选择需要生成招聘发布申请的用人需求池记录");
            }

            var ids = Ids.Select(Guid.Parse).ToList();
            logger.LogInformation("准备生成招聘发布申请，用人需求池数量：{Count}", ids.Count);

            // 使用悲观锁事务避免并发问题
            using var transaction = await DC.Database.BeginTransactionAsync();
            try
            {
                // 查询用人需求池数据和关联的用人需求子表（使用悲观锁）
                var staffPools = await DC.Set<SysHrStaffPool>().Include(x => x.StaffNeedEntry)
                    .ThenInclude(x => x.Group) // 包含部门信息
                    .Include(x => x.StaffNeedEntry)
                    .ThenInclude(x => x.JobPosition) // 包含岗位信息
                    .Where(p => ids.Contains(p.ID))
                    .ToListAsync(); // 移除 AsNoTracking 以支持悲观锁

                if (!staffPools.Any())
                {
                    return new Result<Guid>("未找到有效的用人需求池记录");
                }

                // 验证用人需求池数据完整性
                var validationResult = await ValidateStaffPoolDataAsync(staffPools);
                if (!validationResult.IsSuccess)
                {
                    return new Result<Guid>(validationResult.Message);
                }

                // 校验StaffNeedEntry的OrgId是否一致
                var orgIds = staffPools.Select(p => p.StaffNeedEntry.OrgId).Distinct().Where(id => id.HasValue)
                    .ToList();
                if (orgIds.Count > 1)
                {
                    return new Result<Guid>("选中的用人需求池包含不同的公司，请选择相同公司的记录进行批量操作");
                }

                if (!orgIds.Any())
                {
                    return new Result<Guid>("选中的用人需求池未设置公司，无法进行批量操作");
                }

                // 直接计算所有用人需求池的招聘人数合计
                var totalRecruitCount = staffPools.Sum(p => p.StaffNeedEntry.HireNumber);

                logger.LogInformation("招聘发布申请总人数：{TotalCount}", totalRecruitCount);

                // 获取所有有效的用人需求明细
                var staffNeedEntries = staffPools
                    .Select(p => p.StaffNeedEntry)
                    .ToList();

                // 查询时直接获取需要的字段，避免后续复杂访问
                var staffPoolsWithDetails = staffPools
                    .Select(p => new
                    {
                        Pool = p,
                        BillCode = p.BillNo,
                        GroupName = p.StaffNeedEntry.Group?.GroupName,
                        JobPositionName = p.StaffNeedEntry.JobPosition?.Name,
                        HireNumber = p.StaffNeedEntry.HireNumber
                    })
                    .ToList();

                // 生成备注
                var remarkDetails = staffPoolsWithDetails
                    .Select(x =>
                        $"{x.BillCode ?? "未知单号"}-{x.GroupName ?? "未知部门"}-{x.JobPositionName ?? "未知岗位"}-{x.HireNumber}人")
                    .ToList();

                // 生成标题，格式：部门-岗位-人数
                var titleDetails = staffPoolsWithDetails
                    .Select(x => $"{x.GroupName ?? "未知部门"}-{x.JobPositionName ?? "未知岗位"}-{x.HireNumber}人")
                    .ToList();

                // 生成招聘发布申请单（只有主表）
                var publishBill = new SysHrRecruitPublishRequestBill
                {
                    ID = Uuid.NewDatabaseFriendly(Database.SqlServer),
                    GroupId = Wtm.LoginUserInfo?.Groups?.FirstOrDefault()?.ID,
                    OrgId = orgIds.First(),
                    BillStatus = BillStatus.草稿,
                    WorkflowStatus = WorkflowStatus.待提交,
                    HireNumber = totalRecruitCount, // 设置总招聘人数
                    CreateTime = DateTime.Now,
                    CreateBy = Wtm.LoginUserInfo?.ITCode,

                    // 从所有 SysHrStaffNeedRequestBillEntry 拼接相同字段
                    ExpectedDate = staffNeedEntries.Where(x => x.ExpectedDate.HasValue).Select(x => x.ExpectedDate)
                        .FirstOrDefault(),
                    JobRequirement = string.Join("；",
                        staffNeedEntries.Where(x => !string.IsNullOrEmpty(x.JobRequirement))
                            .Select(x => x.JobRequirement)
                            .Distinct()),
                    EducationRequirement = staffNeedEntries.Where(x => x.EducationRequirement.HasValue)
                        .Select(x => x.EducationRequirement).FirstOrDefault(),
                    MajorRequirement = string.Join("；",
                        staffNeedEntries.Where(x => !string.IsNullOrEmpty(x.MajorRequirement))
                            .Select(x => x.MajorRequirement).Distinct()),
                    GenderRequirement = staffNeedEntries.Where(x => x.GenderRequirement.HasValue)
                        .Select(x => x.GenderRequirement).FirstOrDefault(),
                    AgeRequirement = string.Join("；",
                        staffNeedEntries.Where(x => !string.IsNullOrEmpty(x.AgeRequirement))
                            .Select(x => x.AgeRequirement)
                            .Distinct()),
                    OtherRequirement = string.Join("；",
                        staffNeedEntries.Where(x => !string.IsNullOrEmpty(x.OtherRequirement))
                            .Select(x => x.OtherRequirement).Distinct()),

                    // 设置默认值的字段
                    Title = string.Join("；", titleDetails), // 修改为部门-岗位-人数格式
                    Description = "具备良好职业素养，认真负责，团队协作能力强", // 默认描述
                    SalaryRange = "面议", // 默认薪资范围
                    Benefits = "五险一金，带薪年假等", // 默认福利待遇
                    IsExternalPublish = false, // 默认不对外发布
                    Remark = string.Join("；", remarkDetails) // 添加人数来源明细到备注字段
                };

                // 生成编码
                var codeService = Wtm.ServiceProvider.GetRequiredService<CodeGeneratorService>();
                publishBill.BillCode = await codeService.GenerateCodeAsync(publishBill.GetType().Name);

                // 更新用人需求池的关联关系
                foreach (var pool in staffPools)
                {
                    pool.RecruitPublishRequestBillId = publishBill.ID;
                    pool.IsPublished = false; // 标记为待发布状态
                    pool.HrStatus = HrStatus.已发布;
                    DC.Set<SysHrStaffPool>().Update(pool);
                }

                // 保存到数据库
                await DC.Set<SysHrRecruitPublishRequestBill>().AddAsync(publishBill);
                await DC.SaveChangesAsync();

                // 提交事务
                await transaction.CommitAsync();

                logger.LogInformation("招聘发布申请生成成功，ID：{Id}，关联用人需求池数量：{Count}，总招聘人数：{TotalCount}",
                    publishBill.ID, staffPools.Count, totalRecruitCount);

                return new Result<Guid>
                {
                    Data = publishBill.ID,
                    Message =
                        $"招聘发布申请生成成功，关联 {staffPools.Count} 个用人需求池，总招聘人数 {totalRecruitCount} 人，招聘单号为：{publishBill.BillCode}"
                };
            }
            catch (Exception ex)
            {
                await transaction.RollbackAsync();
                logger.LogError(ex, "生成招聘发布申请失败");
                return new Result<Guid>($"生成失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 验证用人需求池数据完整性
        /// </summary>
        /// <param name="staffPools">用人需求池列表</param>
        /// <returns>验证结果</returns>
        private async Task<(bool IsSuccess, string Message)> ValidateStaffPoolDataAsync(
            List<SysHrStaffPool> staffPools)
        {
            var invalidPools = new List<string>();

            foreach (var pool in staffPools)
            {
                // 检查是否关联了用人需求子表
                if (pool.StaffNeedEntry == null)
                {
                    invalidPools.Add($"用人需求池({pool.BillNo ?? pool.ID.ToString()})未关联用人需求子表");
                    continue;
                }

                // 检查招聘人数是否有效
                if (pool.StaffNeedEntry.HireNumber <= 0)
                {
                    invalidPools.Add($"用人需求池({pool.BillNo ?? pool.ID.ToString()})的招聘人数必须大于0");
                    continue;
                }

                // 严格检查是否已关联招聘发布申请ID
                if (pool.RecruitPublishRequestBillId.HasValue)
                {
                    var existingBill = await DC.Set<SysHrRecruitPublishRequestBill>()
                        .Where(x => x.ID == pool.RecruitPublishRequestBillId.Value)
                        .Where(x => x.WorkflowStatus != WorkflowStatus.已取消) // 排除已取消的申请单
                        .Select(x => x.BillCode)
                        .FirstOrDefaultAsync();

                    if (!string.IsNullOrEmpty(existingBill))
                    {
                        invalidPools.Add($"用人需求池({pool.BillNo ?? pool.ID.ToString()})已关联招聘发布申请({existingBill})，不能重复生成");
                    }
                }
            }

            if (invalidPools.Any())
            {
                return (false, $"以下用人需求池不能生成招聘发布申请：{string.Join("；", invalidPools)}");
            }

            return (true, string.Empty);
        }
    }
}